﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class MonsterBase : MonoBehaviour {
    #region 公有buff
    //某些属性的倍率,属性一般是int型
    public static float MoveSpeedRate=1;
    public static float MaxHPRate=1;
    public static int HurtRate = 1;
    /// <summary>
    /// 设置所有怪物的公有属性
    /// </summary>
    /// <param name="ms">移动速度</param>
    /// <param name="hp">最大生命值</param>
    public static void SetBuff(float ms=1,float hp=1,int hurt=1)
    {
        MoveSpeedRate = ms;
        MaxHPRate = hp;
        HurtRate = hurt;
    }

    #endregion

    public GameObject Target;
    /// <summary>
    /// 实时的HP，初始化时默认设置为最大值
    /// </summary>
    public int HP;
    public int MaxHP;


    private int _maxHP=-5;
    private float _MoveSpeed=-5;

    private Animator animator;//测试 用来播放动画
    private Color _color;


    /// <summary>
    /// 用于初始化,每次active都会启用，如从对象池出来
    /// </summary>
    public virtual void Init()
    {
        isAlive = true;
        Data.Instance.MonsterCount++;
        _color = GetComponent<SpriteRenderer>().color;

        if (_maxHP <= 0)
        {
            _maxHP = MaxHP;
            _MoveSpeed = MoveSpeed;
        }

        MaxHP = (int)(_maxHP * MaxHPRate);
        MoveSpeed = _MoveSpeed * MoveSpeedRate;
        HP = MaxHP;

        Target = GameObject.Find("Player");
    }
    /// <summary>
    /// 初始化，只会运行一次，设置属性可用
    /// </summary>
    public virtual void InitOnce()
    {
        if (faceToLeft)
        {
            //朝向左边
            facingDirection = new Vector2(-1, 0);
        }
        else
        {
            //朝向右边
            facingDirection = new Vector2(1, 0);
        }

        animator = GetComponent<Animator>();//测试动画
    }
    #region 生命周期函数
    private void OnEnable()
    {
        Init();
    }

    private void OnDisable()
    {
        Data.Instance.MonsterCount--;
    }
    private void Start()
    {
        InitOnce();
    }
    private void Update()
    {
        UpdateFunc();
    }
    #endregion
    /// <summary>
    /// 用于更新
    /// </summary>
    public virtual void UpdateFunc()
    {
        DoAction(Move,-1);
    }
    public delegate void Action();

    private bool free=true;
    /// <summary>
    /// 进行动作，可以加上动作的持续时间，在这段时间内无法进行其他动作,小于0表示无CD
    /// </summary>
    /// <param name="action"></param>
    /// <param name="defaultCD"></param>
    public void DoAction(Action action,float defaultCD=3)
    {
        if (free)
        {
            action();
            if (defaultCD < 0)
            {
                return;
            }
            free = false;
            StartCoroutine(CDTimer(defaultCD));
        }
    }
    private IEnumerator CDTimer(float cd)
    {
        yield return new WaitForSeconds(cd);
        free = true;
    }
    /// <summary>
    /// 是否存活，放置多次进入对象池
    /// </summary>
    private bool isAlive = true;
    /// <summary>
    /// 杀死（放入对象池）
    /// </summary>
    public virtual void Die()
    {
        if (!isAlive)
        {
            return;
        }
        isAlive = false;
        Debug.Log(name+"死亡");
        this.GetComponent<SpriteRenderer>().color = _color;
        GameObject de= ObjectPool.Instance.OutPool("Prefabs/DeathEffect");
        de.transform.position = transform.position;
        de.transform.localScale = transform.localScale;
        ObjectPool.Instance.InPool(gameObject);
    }
    #region 碰撞相关
    private void OnCollisionEnter2D(Collision2D collision)
    {
        OnCollision(collision);
    }
    public virtual void OnCollision(Collision2D collision)
    {
        foreach(var p in collision.contacts)
        {
            //撞到障碍物就转身
            if (p.normal.x * facingDirection.x < 0 &&p.normal.y < 0.3
                &&p.collider.gameObject.layer!=8&&
                p.collider.gameObject.layer!=9)
            {
                Turn();
            }
        }
        if (collision.gameObject.layer == 9)
        {
            Hurt(10);
        }
    }
    #endregion
    /// <summary>
    /// 对其造成伤害
    /// </summary>
    /// <param name="damage"></param>
    public void Hurt(int damage)
    {
        HP -= damage * HurtRate;
        if (HP <= 0)
        {
            Die();
            return;
        }
        OnHurt();
    }
    public virtual void OnHurt()
    {
        StartCoroutine(ChangeColor());
    }
    /// <summary>
    /// 变红
    /// </summary>
    /// <returns></returns>
    private IEnumerator ChangeColor()
    {
        float c = GetComponent<SpriteRenderer>().color.g;
        c = Mathf.Clamp(c,0.5f,1);
        GetComponent<SpriteRenderer>().color = new Color(
            GetComponent<SpriteRenderer>().color.r, 
            c-0.5f, 
            c-0.5f);
        while (GetComponent<SpriteRenderer>().color.g < c)
        {
            yield return new WaitForEndOfFrame();
            GetComponent<SpriteRenderer>().color = new Color(
                GetComponent<SpriteRenderer>().color.r,
                GetComponent<SpriteRenderer>().color.g+0.05f, 
                GetComponent<SpriteRenderer>().color.b+0.05f);
        }

    }
    #region 移动相关
    /// <summary>
    /// 转身
    /// </summary>
    protected void Turn()
    {
        facingDirection *= -1;
        transform.localScale = new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z);
    }
    [Tooltip("是否面向左边，这个是用来判断单位朝向的，\n跟素材有关。朝向影响转身，移动等")]
    public bool faceToLeft = true;
    private Vector2 facingDirection;
    public float MoveSpeed=3;
    private bool canMove = true;
    /// <summary>
    /// 移动，默认是朝前的
    /// </summary>
    public virtual void Move()
    {
        if (canMove)
        {
            transform.Translate(facingDirection * Time.deltaTime * MoveSpeed, Space.World);
            animator.Play(Animator.StringToHash("crab_walk"));//测试动画
        }
        else
        {
            animator.Play(Animator.StringToHash("crab_idle"));//测试动画
        }
    }
    #endregion



}